import json
import logging

from django.db.models import Q
from django.http import JsonResponse
from django.utils import timezone

from rest_framework.views import APIView

from menu.models import SysRoleMenu, SysMenu
from monitor_alert_center.models import MonitorGroup
from role.models import SysRole, SysRoleSerializer, SysUserRole, SysRoleGroupList, SysRoleMonitorGroup

from utils.page_data import PageData
from utils.check_permission import check_permission

logger = logging.getLogger()
# 修改权限
logger.setLevel(logging.INFO)

class CheckRoleView(APIView):
    """获取所有角色"""

    def get(self, request):
        role_queryset = SysRole.objects.all().values()
        return JsonResponse({"code": 200, "msg": list(role_queryset)})


class SearchRolesView(APIView):
    """查询角色列表"""

    @check_permission(perms_list=['system:role:list'])  # 直接应用装饰器，无需method_decorator
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def post(self, request):
        data = json.loads(request.body.decode("utf-8"))
        query = data["query"]
        page_num = data["pageNum"]  # 当前页
        page_size = data["pageSize"]  # 每页大小
        all_role_queryset = SysRole.objects.filter(name__icontains=query).order_by('id').values()

        obj = PageData(all_role_queryset, page_size, page_num)
        role_list = obj.get_search()
        for item in role_list:
            try:
                item['create_time'] = item['create_time'].strftime('%Y-%m-%d %H:%M:%S')
                item['update_time'] = item['update_time'].strftime('%Y-%m-%d %H:%M:%S')
            except AttributeError as e:
                logger.error(str(e))
        total = all_role_queryset.count()
        return JsonResponse({"code": 200, "msg": role_list, "total": total})


class ActionCheckRoleView(APIView):
    """获取新建角色的数据"""

    @check_permission(perms_list=['system:role:list'])  # 直接应用装饰器，无需method_decorator
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def get(self, request):
        role_id = request.GET.get('id')
        obj = SysRole.objects.get(id=role_id)
        if obj:
            return JsonResponse({"code": 200, "msg": SysRoleSerializer(obj).data})
        return JsonResponse({"code": 500, 'msg': '角色不存在'})


class SaveView(APIView):
    """保存角色信息"""

    @check_permission(perms_list=['system:role:list'])  # 直接应用装饰器，无需method_decorator
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def post(self, request):
        try:
            data = json.loads(request.body.decode("utf-8"))
            if data["id"] == -1:  # 添加
                exits_role = SysRole.objects.filter(Q(name=data['name']) | Q(code=data['code']))
                if exits_role:
                    return JsonResponse({"code": 500, "msg": "角色名或者权限字符已存在，请更换"})
                SysRole.objects.create(name=data['name'], code=data['code'], remark=data['remark'])
            else:  # 修改
                old_role = SysRole.objects.filter(id=data['id']).get()
                if (old_role.name == data['name'] and old_role.code == data['code']
                        and old_role.remark == data['remark']):
                    return JsonResponse({"code": 500, "msg": "未做任何修改"})

                exits_role = (SysRole.objects
                              .exclude(id=data['id'])
                              .filter(Q(name=data['name']) | Q(code=data['code'])).exists())
                if exits_role:
                    return JsonResponse({"code": 500, "msg": "角色名或者权限字符已存在，请更换"})

                if data['code'] == 'admin' or data['name'] == '超级管理员' or data['id'] == 1:
                    return JsonResponse({"code": 500, "msg": "禁止操作admin角色"})

                (SysRole.objects.filter(id=data['id'])
                 .update(name=data['name'], code=data['code'], update_time=timezone.now(),
                         create_time=data['create_time'], remark=data['remark']))
        except Exception as e:
            logging.error(e)
            return JsonResponse({'code': 500, 'msg': '执行失败'})
        return JsonResponse({'code': 200})


class DelRoleView(APIView):
    """删除角色"""

    @check_permission(perms_list=['system:role:list'])  # 直接应用装饰器，无需method_decorator
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def delete(self, request):
        id_list = json.loads(request.body.decode("utf-8"))
        SysUserRole.objects.filter(role_id__in=id_list).delete()
        SysRoleMenu.objects.filter(role_id__in=id_list).delete()
        SysRole.objects.filter(id__in=id_list).delete()
        return JsonResponse({"code": 200})


class GetMenusView(APIView):
    """根据角色查询菜单权限"""

    @check_permission(perms_list=['system:role:list'])  # 直接应用装饰器，无需method_decorator
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def get(self, request):
        id = request.GET.get('id')
        menu_list = SysRoleMenu.objects.filter(role_id=id).values('menu_id')
        menu_id_list = [item['menu_id'] for item in menu_list]
        return JsonResponse({"code": 200, "msg": menu_id_list})


class GrantMenu(APIView):
    """角色功能授权"""

    @check_permission(perms_list=['system:role:list'])  # 直接应用装饰器，无需method_decorator
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def post(self, request):
        data = json.loads(request.body.decode("utf-8"))
        role_id = data['id']
        menu_id_list = data['menuIds']
        try:
            # 判断前端传来的menu 列表中，是否有主机管理的menu id
            host_menu = SysMenu.objects.filter(perms="host:list").get()

            if host_menu.id not in menu_id_list:
                job_list = SysMenu.objects.filter(perms__in=['job:list', 'file:list']).values_list('id')
                for item in job_list:
                    if item[0] in menu_id_list:
                        return JsonResponse({"code": 500, "msg": "主机相关的权限，需要主机管理权限支持"})

                SysRoleGroupList.objects.filter(role_id=role_id).delete()  # 删除角色主机分组关联表中的指定角色的数据

            role_menu_obj = SysRoleMenu.objects
            role_menu_obj.filter(role_id=role_id).delete()  # 删除角色菜单关联表中的指定角色的数据
            for menu_id in menu_id_list:
                role_menu_obj.create(role_id=role_id, menu_id=menu_id)
        except Exception as e:
            logging.error(e)
            return JsonResponse({"code": 500, "msg": "功能授权失败，请联系管理员"})
        return JsonResponse({"code": 200})


class GrantHostView(APIView):
    """角色主机分组授权"""

    @check_permission(perms_list=['system:role:list'])  # 直接应用装饰器，无需method_decorator
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def post(self, request):
        data = json.loads(request.body.decode("utf-8"))
        role_id = data['role_id']
        group_list = data['groups']
        try:
            SysRoleGroupList.objects.filter(role_id=role_id).delete()  # 删除角色主机分组关联表中的指定角色的数据
            for group_id in group_list:
                SysRoleGroupList.objects.create(role_id=role_id, group_id=group_id)
        except Exception as e:
            logging.error(e)
            return JsonResponse({"code": 500, "msg": "主机分组授权失败，请联系管理员"})
        return JsonResponse({"code": 200})


class GetHostsView(APIView):
    """根据角色查询主机分组权限"""

    @check_permission(perms_list=['system:role:list'])  # 直接应用装饰器，无需method_decorator
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def get(self, request):
        id = request.GET.get('id')
        try:
            group_list = SysRoleGroupList.objects.filter(role_id=id).values('group_id')
            group_id_list = [item['group_id'] for item in group_list]
        except Exception as e:
            logging.error(e)
            return JsonResponse({"code": 500, "msg": "主机分组查询失败，请联系管理员"})
        return JsonResponse({"code": 200, "msg": group_id_list})


class GrantMonitorGroupView(APIView):
    """角色监控分组授权"""

    @check_permission(perms_list=['system:role:list'])  # 直接应用装饰器，无需method_decorator
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def post(self, request):
        data = json.loads(request.body.decode("utf-8"))
        role_id = data['role_id']
        group_list = data['groups']
        try:
            # 1、先删除角色主机分组关联表中的指定角色的数据
            SysRoleMonitorGroup.objects.filter(role_id=role_id).delete()

            # 2、再增加角色授权数据
            for group_id in group_list:
                SysRoleMonitorGroup.objects.create(role_id=role_id, group_id=group_id)
        except Exception as e:
            logging.error(e)
            return JsonResponse({"code": 500, "msg": "主机分组授权失败，请联系管理员"})
        return JsonResponse({"code": 200})


class GetMonitorGroupView(APIView):
    """根据角色查询监控分组权限"""

    @check_permission(perms_list=['system:role:list'])  # 直接应用装饰器，无需method_decorator
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def get(self, request):
        id = request.GET.get('id')
        try:
            group_list = SysRoleMonitorGroup.objects.filter(role_id=id).values('group_id')
            group_id_list = [item['group_id'] for item in group_list]
        except Exception as e:
            logging.error(e)
            return JsonResponse({"code": 500, "msg": "告警分组查询失败，请联系管理员"})
        return JsonResponse({"code": 200, "msg": group_id_list})


class GetAllMonitorGroupView(APIView):
    """获取所有监控分组数据"""

    @check_permission(perms_list=['system:role:list'])  # 直接应用装饰器，无需method_decorator
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def get(self, request):
        try:
            group_list = MonitorGroup.objects.values('id', 'name')
        except Exception as e:
            logging.error(e)
            return JsonResponse({"code": 500, "msg": "获取所有告警分组失败，请联系管理员"})
        return JsonResponse({"code": 200, "msg": list(group_list)})
